Skip to content

fix: removed duplicate code in KubeConfigUpdate. Added tests#310

Open
adietish wants to merge 1 commit into
redhat-developer:mainfrom
adietish:dedupe_kubeconfigupdate
Open

fix: removed duplicate code in KubeConfigUpdate. Added tests#310
adietish wants to merge 1 commit into
redhat-developer:mainfrom
adietish:dedupe_kubeconfigupdate

Conversation

@adietish
Copy link
Copy Markdown
Collaborator

No description provided.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Create kubeconfig contexts using client-certificate authentication.
    • Improved handling to generate unique context/user names to avoid collisions.
  • Bug Fixes

    • Token updates now clear existing client-certificate data when switching auth methods.
    • Persistence improvements ensure current-context and kubeconfig changes are saved consistently across files.

Walkthrough

Refactors KubeConfigUpdate to inject a persisterFactory and centralize persistence and context-entry creation; exposes KubeConfigNamedContext.toName as @JvmStatic; adds client-certificate flows and updates tests to use injected ConfigPersister mocks.

Changes

Kubeconfig persistence and context refactoring

Layer / File(s) Summary
Expose toName() as Java-callable static method
src/main/kotlin/.../KubeConfigEntries.kt
toName() in KubeConfigNamedContext companion object is changed from private to @JvmStatic, making it callable from Java as a static method.
Centralize persistence infrastructure in base class
src/main/kotlin/.../KubeConfigUpdate.kt
KubeConfigUpdate constructor accepts a persisterFactory parameter. New saveConfigs and saveConfig helper methods centralize kubeconfig write decisions based on path and context changes. Persister instantiation switches to use the injected factory.
Move context creation and name uniqueness logic to base class
src/main/kotlin/.../KubeConfigUpdate.kt
Context entry creation, unique user/cluster/context name generation, and existing-name collection across all configs are moved from subclasses to a shared base-class ContextEntries data structure and helper methods. UpdateToken now clears client cert fields when setting a token.
Refactor UpdateClientCert and CreateContextWithClientCert subclasses
src/main/kotlin/.../KubeConfigUpdate.kt
UpdateClientCert and CreateContextWithClientCert now accept persisterFactory injection and delegate context entry creation and persistence to base-class helpers; they set/remove token and certificate fields as appropriate and persist via shared save helpers.
OpenShift user creation helpers
src/main/kotlin/.../OpenShiftClientFactory.kt
createUser now constructs a mutable user map and delegates token vs client-certificate population to setToken and setClientCertificates helper methods.
Test helpers: PEM import and user-with-client-cert factory
src/test/kotlin/.../KubeConfigTestHelpers.kt
Add PemUtils import and createUserMapWithClientCert(...) to build test user maps including base64-encoded client-certificate-data and client-key-data.
Test infrastructure refactoring and client-cert/token suites
src/test/kotlin/.../KubeConfigUpdateTest.kt
Tests use an injected mocked ConfigPersister factory instead of constructing persisters or temp files. Added CreateContextWithClientCert tests, expanded UpdateToken and UpdateClientCert tests (persistence, current-context, token/cert interaction), migrated CreateContext uniqueness/null-field tests, and added test data/classes and helpers for client-cert verification and mock setup.

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess relevance to the changeset. Add a pull request description that explains the changes, motivation, and any relevant context for the reviewers.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main objective of the PR: removing duplicate code in KubeConfigUpdate and adding tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adietish adietish self-assigned this May 26, 2026
@adietish adietish moved this to Ready for Review in Eclipse Che Team C Backlog May 26, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt (1)

74-75: ⚡ Quick win

Avoid positional saveConfig overloads with identical collection types.

These overloads take users, clusters, and contexts as separate ArrayList<Any?> parameters, and the private delegate reorders them. A future call-site swap will still compile and can write a malformed kubeconfig. Passing ContextEntries directly would make this helper much safer.

Refactor direction
-    protected fun saveConfig(
-        config: KubeConfig,
-        users: ArrayList<Any?>,
-        clusters: ArrayList<Any?>,
-        contexts: ArrayList<Any?>,
-        currentContext: String
-    ) {
-        saveConfig(contexts, clusters, users, config.preferences, currentContext, config.path)
-    }
+    protected fun saveConfig(config: KubeConfig, entries: ContextEntries) {
+        saveConfig(
+            entries.contexts,
+            entries.clusters,
+            entries.users,
+            config.preferences,
+            entries.currentContextName,
+            config.path
+        )
+    }

Then update the two callers to pass entries / contextEntries directly.

Also applies to: 85-95

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt`
around lines 74 - 75, The saveConfig overloads currently accept separate
ArrayList<Any?> for users, clusters, and contexts which is error-prone; change
the private helper signature (the delegated saveConfig) to accept the
strongly-typed ContextEntries (or the appropriate ContextEntries wrapper type)
instead of positional ArrayList<Any?> parameters, update the two callers that
currently pass entries / contextEntries to pass the ContextEntries object
directly, and remove any manual reordering logic inside saveConfig so the
original entries are preserved by type; reference the saveConfig overloads and
the callers that pass entries/contextEntries to locate the changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt`:
- Around line 209-214: When setting a token in setTokenFor (and in the
UpdateToken flow), also clear any existing client cert fields to avoid
presenting both credentials: after Utils.setValue(this, token,
arrayOf("user","token")) remove or null out "user.client-certificate-data" and
"user.client-key-data" on the same user object (use the existing Utils helpers —
e.g., Utils.setValue(this, null, arrayOf("user","client-certificate-data")) /
Utils.setValue(this, null, arrayOf("user","client-key-data")) or the
Utils.removeValue equivalent) so UpdateToken mirrors UpdateClientCert's behavior
of removing the opposite auth field.

In
`@src/test/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdateTest.kt`:
- Around line 29-32: The tests currently use a single mock (mockPersister)
returned by testPersisterFactory so they only assert multiple save() calls
rather than per-file routing; change testPersisterFactory to create and return a
distinct mock ConfigPersister for each File (store them in a map keyed by
File/path) and update assertions to verify each file's dedicated mock was
invoked exactly once (e.g., verify(exactly = 1) {
persistersByFile[userFile].save(...) } and verify for the other file including
the context name matcher) so the test validates that each config file is
persisted by its own factory-produced persister.

---

Nitpick comments:
In `@src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt`:
- Around line 74-75: The saveConfig overloads currently accept separate
ArrayList<Any?> for users, clusters, and contexts which is error-prone; change
the private helper signature (the delegated saveConfig) to accept the
strongly-typed ContextEntries (or the appropriate ContextEntries wrapper type)
instead of positional ArrayList<Any?> parameters, update the two callers that
currently pass entries / contextEntries to pass the ContextEntries object
directly, and remove any manual reordering logic inside saveConfig so the
original entries are preserved by type; reference the saveConfig overloads and
the callers that pass entries/contextEntries to locate the changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: d0d178b7-c346-4934-b30f-3011c0683346

📥 Commits

Reviewing files that changed from the base of the PR and between 9f7b425 and c40fe65.

📒 Files selected for processing (3)
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigEntries.kt
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt
  • src/test/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdateTest.kt

@adietish adietish force-pushed the dedupe_kubeconfigupdate branch from c40fe65 to 30e9536 Compare June 1, 2026 12:41
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jun 1, 2026

Codecov Report

❌ Patch coverage is 75.75758% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 23.17%. Comparing base (71098f6) to head (2126dbb).
⚠️ Report is 351 commits behind head on main.

Files with missing lines Patch % Lines
...vtools/gateway/openshift/OpenShiftClientFactory.kt 0.00% 13 Missing ⚠️
...at/devtools/gateway/kubeconfig/KubeConfigUpdate.kt 87.20% 5 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##            main     #310       +/-   ##
==========================================
+ Coverage   0.00%   23.17%   +23.17%     
==========================================
  Files          4       99       +95     
  Lines         26     4182     +4156     
  Branches       0      770      +770     
==========================================
+ Hits           0      969      +969     
- Misses        26     3089     +3063     
- Partials       0      124      +124     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adietish adietish force-pushed the dedupe_kubeconfigupdate branch 2 times, most recently from bdb5da6 to 65b246a Compare June 1, 2026 13:28
@adietish
Copy link
Copy Markdown
Collaborator Author

adietish commented Jun 1, 2026

@vrubezhny, @azatsarynnyy: please review

Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Assisted-by: Cursor <cursoragent@cursor.com>
@adietish adietish force-pushed the dedupe_kubeconfigupdate branch from d6453ac to 2126dbb Compare June 1, 2026 15:11
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/kotlin/com/redhat/devtools/gateway/openshift/OpenShiftClientFactory.kt`:
- Around line 281-290: createUser currently inconsistently detects token auth
(checks token != null elsewhere but here also requires token.isNotEmpty()),
which allows an empty token and absent certs to produce a user with no auth; fix
by making the branch consistent: either (A) treat any non-null token as token
auth by removing token.isNotEmpty() so setToken(token, user) is called when
token != null, or (B) explicitly validate and fail fast—if token != null but
token.isEmpty() and clientCert/clientKey are null, throw an
IllegalArgumentException (or log and throw) instead of falling through to
setClientCertificates; update the logic in createUser and keep using the
existing helper functions setToken and setClientCertificates to populate the
user map.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: f2acc3c6-103b-4dba-bbb4-6720e6c871c9

📥 Commits

Reviewing files that changed from the base of the PR and between d6453ac and 2126dbb.

📒 Files selected for processing (5)
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigEntries.kt
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt
  • src/main/kotlin/com/redhat/devtools/gateway/openshift/OpenShiftClientFactory.kt
  • src/test/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigTestHelpers.kt
  • src/test/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdateTest.kt
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigEntries.kt
  • src/test/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdateTest.kt
  • src/main/kotlin/com/redhat/devtools/gateway/kubeconfig/KubeConfigUpdate.kt

Comment on lines 281 to 290
private fun createUser(usingToken: Boolean, token: CharArray?, clientCert: CertificateSource?, clientKey: CertificateSource?): Map<String, Any> {
val userAuth = mutableMapOf<String, Any>()
val user = mutableMapOf<String, Any>()

if (usingToken
&& token != null
&& token.isNotEmpty()) {
userAuth["token"] = String(token).trim()
setToken(token, user)
} else {
clientCert?.let { cert ->
if (cert.isFilePath) {
userAuth["client-certificate"] = cert.value.trim()
} else {
userAuth["client-certificate-data"] = PemUtils.toBase64(cert.value.trim())
}
}
clientKey?.let { key ->
if (key.isFilePath) {
userAuth["client-key"] = key.value.trim()
} else {
userAuth["client-key-data"] = PemUtils.toBase64(key.value.trim())
}
}
setClientCertificates(clientCert, clientKey, user)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix inconsistent token-auth detection to avoid empty-auth kubeconfig users.

Line 235 treats any non-null token as token auth, but Line 285 additionally requires token.isNotEmpty(). With an empty token and no certs, this path writes no auth fields at all, producing an invalid user entry instead of failing fast.

Proposed fix
 private fun createKubeConfig(
@@
-        val usingToken = token != null
+        val usingToken = token?.isNotEmpty() == true
         val usingClientCert = clientCert != null && clientKey != null

         require(usingToken.xor(usingClientCert)) {
             "Provide either token OR clientCert + clientKey."
         }
@@
-    private fun createUser(usingToken: Boolean, token: CharArray?, clientCert: CertificateSource?, clientKey: CertificateSource?): Map<String, Any> {
+    private fun createUser(usingToken: Boolean, token: CharArray?, clientCert: CertificateSource?, clientKey: CertificateSource?): Map<String, Any> {
         val user = mutableMapOf<String, Any>()

-        if (usingToken
-            && token != null
-            && token.isNotEmpty()) {
+        if (usingToken && token != null) {
             setToken(token, user)
         } else {
             setClientCertificates(clientCert, clientKey, user)
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/kotlin/com/redhat/devtools/gateway/openshift/OpenShiftClientFactory.kt`
around lines 281 - 290, createUser currently inconsistently detects token auth
(checks token != null elsewhere but here also requires token.isNotEmpty()),
which allows an empty token and absent certs to produce a user with no auth; fix
by making the branch consistent: either (A) treat any non-null token as token
auth by removing token.isNotEmpty() so setToken(token, user) is called when
token != null, or (B) explicitly validate and fail fast—if token != null but
token.isEmpty() and clientCert/clientKey are null, throw an
IllegalArgumentException (or log and throw) instead of falling through to
setClientCertificates; update the logic in createUser and keep using the
existing helper functions setToken and setClientCertificates to populate the
user map.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants